/*
*
给你一个整数 n ，返回 和为 n 的完全平方数的最少数量 。

完全平方数 是一个整数，其值等于另一个整数的平方；换句话说，其值等于一个整数自乘的积。例如，1、4、9 和 16 都是完全平方数，而 3 和 11 不是。

示例 1：

输入：n = 12
输出：3
解释：12 = 4 + 4 + 4
示例 2：

输入：n = 13
输出：2
解释：13 = 4 + 9

提示：

1 <= n <= 104

  - @author ala
  - @date 2024-10-11 17:16
*/
package main

import (
	"fmt"
	"math"
)

func main() {
	n := 13

	fmt.Println(numSquares(n))
}

/**
 *	1）拿到小于等于n的所有完全平方数列表。相当于coins
 *	1）dp[i]表示：凑出i的完全平方数的最小个数
 *		dp[0] = 0
 *		dp[i] = min(dp[i - coins[j] + 1)
 */
func numSquares(n int) int {
	coins := squaresLessN(n)
	dp := make([]int, n+1)
	for i := range dp {
		dp[i] = INF
	}
	dp[0] = 0

	for _, c := range coins {
		for i := c; i <= n; i++ {
			dp[i] = min(dp[i], dp[i-c]+1)
		}
	}
	if dp[n] == INF {
		return -1
	}
	return dp[n]
}

var (
	INF = math.MaxInt32 >> 1
)

func squaresLessN(n int) []int {
	r := make([]int, 0)
	for i := 1; i*i <= n; i++ {
		r = append(r, i*i)
	}
	return r
}
